package service;

/**
 * 业务服务对象的一些标准 关注于业务逻辑的实现,实现清晰的业务接口定义 逻辑清晰,代码简约 业务操作应该具有日志纪录 捕获异常必须写入日志
 * 尽量采用EJB标准或Hibernate的SQL 如果可能,尽量采用命名查询 SQL语句尽量避免非标准以及过于复杂的SQL,避免依赖数据库特定的函数
 * 将一部分SQL完成的功能放到Java里实现来消除对特定数据库的依赖(如格式转换问题,日期样式等) 查询语句尽量采用参数化的方式避免直接写入SQL语句
 * 适当注意SQL的执行时间长短. 用好AppException 必须写单元测试
 */
import java.util.Collection;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import beans.Role;

import domain.UserAccount;
import exceptions.AppException;

/**
 * 用户帐号业务服务.
 * @author spring
 */
public class UserAccountService {

    /** Hibernate SessionFactory. */
    private SessionFactory sessionFactory;

    /**
     * Logger for this class.
     */
    private static final Logger logger = Logger
            .getLogger(UserAccountService.class);

    /**
     * 用户登陆的业务过程,登陆成功返回UserAccount,否则返回null.
     * @param userid 账号ID
     * @param pass 密码
     * @return UserAccount
     */
    public UserAccount loginIn(String userid, String pass) {
        logger.info("user try logging " + userid);
        Session ss = sessionFactory.getCurrentSession();
        UserAccount account = (UserAccount) ss.get(UserAccount.class, userid);

        if (null == account) {
            logger.warn("trying login system use account " + userid);
            return null;
        }
        if (pass.equals(account.getPassword())) {
            logger.info("success lognined use account " + userid);
            return account;
        } else {
            logger.warn("trying login system use account with bad password "
                    + userid);
            return null;
        }

    }
    /**
     * 取得角色列表.
     * @return list
     */
    public Collection<Role> getRoles() {
        return UserAccount.ROLE_MAP.values();
    }
    /**
     * 取得某个账号的信息.
     * @param userid 账号ID
     * @return UserAccount
     */
    public UserAccount getUserAccountByUserid(String userid) {
        return (UserAccount) sessionFactory.getCurrentSession().get(
                UserAccount.class, userid);
    }

    /**
     * 取得所有用户帐号信息.
     * @return Collection of UserAccount
     */
    @SuppressWarnings("unchecked")
    public Collection<UserAccount> getUserAccounts() {
        Query qry = sessionFactory.getCurrentSession().getNamedQuery(
                "UserAccount.getAllUsers");
        return qry.list();

    }

    /**
     * 删除用户帐号.
     * @param userID 要删除的账号ID
     */
    public void deleteUserAccount(String userID) {

        logger.info(" delete user account " + userID);
        Session session = sessionFactory.getCurrentSession();
        session
                .createQuery(
                        "delete from UserAccount user where userID=:userID")
                .setParameter("userID", userID).executeUpdate();

    }

    /**
     * 更新用户帐号 只更新昵称、角色等信息.
     * @param updatedAccount account to update
     * @return UserAccount
     */
    public UserAccount updateUserAccount(UserAccount updatedAccount) {
        Session session = sessionFactory.getCurrentSession();
        UserAccount existAccount = (UserAccount) session.get(UserAccount.class,
                updatedAccount.getUserID());
        if (existAccount == null) {
            throw new AppException("errors.noSuchAccount");
        }
        // 更新字段值
        existAccount.setRoleID(updatedAccount.getRoleID());
        existAccount.setUserName(updatedAccount.getUserName());
        logger.info("updated user account info " + updatedAccount.getUserID());
        return existAccount;
    }

    /**
     * 更改用户帐号密码(同时更改密码更新时间).
     * @param userID 用户名.
     * @param newPassword 新密码.
     */
    public void updatePassword(String userID, String newPassword) {
        Session ss = sessionFactory.getCurrentSession();
        UserAccount existAccount = (UserAccount) ss.get(UserAccount.class,
                userID);
        if (existAccount == null) {
            throw new AppException("errors.noSuchAccount");
        }
        existAccount.setPassword(newPassword);
        existAccount.setPasswordLastChangeDate(new java.sql.Date(System
                .currentTimeMillis()));
        logger.info("updated password " + userID);
    }

    /**
     * @param userAccount 要添加的新帐号.
     */
    public void addNewAccount(UserAccount userAccount) {
        sessionFactory.getCurrentSession().save(userAccount);
        logger.info("created new user account " + userAccount.getUserID());

    }

    /**
     * set session factory.
     * @param pSessionFactory sessionFactory.
     */
    public void setSessionFactory(SessionFactory pSessionFactory) {
        sessionFactory = pSessionFactory;
    }

}
